home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
UTIL
/
FILEUTIL
/
SUPPORT100
/
Source
/
Splitf_c
< prev
next >
Wrap
Text File
|
1995-02-04
|
19KB
|
391 lines
/********************************************************************************/
/* */
/* Splitf.c */
/* Part of Splitf and Joinf distribution */
/* version 1.13, © 1993-1995 Adam Hamilton */
/* See the README file for copyright information */
/* */
/********************************************************************************/
/*********************************/
/* Include required header files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
/**********************************/
/* Program macros and definitions */
#ifndef Bool
# define Bool char
#endif
#define False 0
#define True !False
#define MIN(a, b) (a < b ? a : b)
#define MAX(a, b) (a > b ? a : b)
#ifndef LEAFNAME_MAX
# define LEAFNAME_MAX FILENAME_MAX
#endif
/********************************************************************************/
/* */
/* Function : usage */
/* Description : Displays program usage to standard error, and exits. */
/* Arguments : progname - pointer to character string containing the program */
/* name. */
/* Returns : None. */
/* */
/********************************************************************************/
void usage (char *progname)
{
fprintf (stderr, "File splitter. Version 1.13 - 4th Feburary 1995 by A.Hamilton\n\n");
fprintf (stderr, "Usage : %s [options] <filename>\n\n", progname);
fprintf (stderr, "Options (can be abbreviated) :\n");
fprintf (stderr, " -filesize [filesize in K] default = 1423\n");
#ifndef PC
fprintf (stderr, " -buffersize [buffersize in K] default = 32\n");
#endif
fprintf (stderr, " -path [new path]\n");
fprintf (stderr, " -interactive\n");
exit (EXIT_FAILURE);
}
/********************************************************************************/
/* */
/* Function : examine_filename */
/* Description : Splits filename into component parts. */
/* Arguments : original_name - character array, filename to be examined. */
/* name - pointer to a character array in which to store */
/* file leafname (excluding extention). */
/* ext - pointer to a character array in which to store */
/* the source files extention (if any). */
/* Returns : If the source file has an extention, then return ".spt", */
/* otherwise return "". */
/* */
/********************************************************************************/
char *examine_filename (char original_name[], char *name, char *ext)
{
char main_name[256]; /* Temporary store for leafname. */
char *original; /* Pointer to start of leafname. */
char *pointer; /* Pointer to any ':' characters found. */
register int i = -1, n; /* Pointer & counter. */
if (COLON) /* If our system uses ':' in */
pointer = strrchr (original_name, ':'); /* the file path, then remember */
else /* where it is. */
pointer = NULL;
original = strrchr (original_name, SEPARATOR_SEARCH); /* Find the address where the */
if ((original = MAX (original, pointer)) == NULL) /* leafname starts. */
original = original_name;
else {
original++;
}
do {
i++;
main_name[i] = original[i]; /* Get files leafname */
} while (main_name[i] != '.' && main_name[i] != '\0'); /* (excluding any extention). */
for (n = 0; (ext[n] = original[i]) != '\0'; n++, i++) ; /* Now copy any extention. */
if (main_name[i - n] == '\0') { /* If the file doesn't have an */
strcpy (name, main_name); /* extention, copy the leafname */
return (""); /* and return an empty string. */
}
main_name[i - n] = '\0'; /* Otherwise, terminate the */
strcpy (name, main_name); /* leafname, copy it, and */
return (".spt"); /* the output extention to use. */
}
/********************************************************************************/
/* */
/* Function : numtostr */
/* Description : Converts a number into a 2 didget character string. */
/* Arguments : number - number to be converted. */
/* name - pointer to a character array to store the number. */
/* Returns : None. */
/* */
/********************************************************************************/
void numtostr (short number, char *name)
{
name[0] = (short) (number / 10) + '0';
name[1] = (number % 10) + '0';
name[2] = '\0';
}
/********************************************************************************/
/* */
/* Function : main */
/* Description : Main control function. */
/* Arguments : Command line parameters. */
/* Returns : Exit status. */
/* */
/********************************************************************************/
int main (int argc, char **argv)
{
char source_filename[256]; /* Source filename. */
char out_filename[256]; /* Output leafname. */
char out_path[256]; /* Output path. */
char file_ext[32]; /* Output extention. */
char out_name[256]; /* Full output filename. */
char header[50]; /* Output file header. */
char fnum[3]; /* Output part number. */
char *progname; /* Program name. */
char string[256]; /* Input string. */
char type[5]; /* Filetype (Acorn systems only). */
char interactive = 0; /* Interactive status flag. */
char orig_ext[20]; /* Original filename extention. */
short file_number = 0; /* Current part number. */
long disk_size = 1423 * 1024; /* Output part size (default 1423K). */
long read_size = 32 * 1024; /* Buffer size (default 32K). */
long data_size;
long out_position; /* Position within output file. */
long in_position; /* Position within input file. */
long bytes_read; /* Number of bytes read. */
long bytes_written; /* Number of bytes written. */
long file_length; /* Length of source file. */
long *buffer; /* Pointer to buffer. */
int args; /* Number of command line arguments. */
int i; /* Counter. */
FILE *source_file; /* Source file ID. */
FILE *out_file; /* Output file ID. */
#ifdef ACORN
_kernel_swi_regs regs;
_kernel_oserror *err;
#endif
progname = *argv; /* Get the program name. */
out_path[0] = '\0'; /* Set path to CWD. */
source_filename[0] = '\0'; /* Clear source filename. */
strcpy (type, "0"); /* No filetype set. */
args = argc - 1; /* Initialise count of arguments. */
if (!args) usage (progname); /* If no arguments supplied, show usage.*/
while (args--) {
argv++; /* Look at next argument. */
if (!strncmp ("-filesize", *argv, MAX (2, strlen (*argv)))) { /* -filesize */
if (!args) {
fprintf (stderr, "File size required.\n\n");
usage (progname);
}
disk_size = (long) atoi (*++argv) * 1024; /* Read file size. */
args--;
}
#ifndef PC
else if (!strncmp ("-buffersize", *argv, MAX (2, strlen (*argv)))) { /* -buffersize */
if (!args) {
fprintf (stderr, "Buffer size required\n\n");
usage (progname);
}
read_size = (long) atoi (*++argv) * 1024; /* Read buffer size. */
args--;
}
#endif
else if (!strncmp ("-path", *argv, MAX (2, strlen (*argv)))) { /* -path */
if (!args) {
fprintf (stderr, "Path required\n\n");
usage (progname);
}
sprintf (out_path, "%s%c", *++argv, FILE_SEPARATOR); /* Read new output path.*/
args--;
}
else if (!strncmp ("-interactive", *argv, MAX (2, strlen (*argv)))) /* -interactive */
interactive = 1;
else {
strcpy (source_filename, *argv); /* Read source filename.*/
if (args) usage (progname);
}
}
if (source_filename[0] == NULL) {
fprintf (stderr, "Source filename required\n\n");
usage (progname);
}
/* Get file detail from source filename.*/
strcpy (file_ext, examine_filename (source_filename, out_filename, orig_ext));
out_filename[MIN (LEAFNAME_MAX, 256) - 2] = '\0'; /* and reduce if necessary. */
source_file = fopen (source_filename, "rb"); /* Open read binary source file. */
if (source_file == NULL) { /* Report if error, and stop. */
fprintf (stderr, "Fatal error opening %s for input.\n", source_filename);
exit (EXIT_FAILURE);
}
printf ("Using file size of %ld bytes.\n", disk_size);
fseek (source_file, 0L, SEEK_END); /* Set file pointer to end of file, */
file_length = ftell (source_file); /* get file length */
fseek (source_file, 0L, SEEK_SET); /* and reset pointer to the start. */
if (file_length <= disk_size) {
fprintf (stderr, "No need to split file.\n");
fclose (source_file);
exit (EXIT_SUCCESS);
}
buffer = (long *) malloc ((size_t) read_size); /* Allocate memory for a buffer. */
if (buffer == NULL) {
fprintf (stderr, "Fatal error, unable to allocate memory block of %ld bytes\n", read_size);
exit (EXIT_FAILURE);
}
printf ("Using buffer size of %ld bytes.\n", read_size);
#ifdef ACORN
regs.r[0] = 5; /* Perform an OS_File to read file data. */
regs.r[1] = (int) source_filename;
err = _kernel_swi (SWI_OS_File, ®s, ®s);
if (err != NULL || (regs.r[0] != 1 && regs.r[0] != 3)) {
fprintf (stderr, "Fatal error, %s is not a file\n", source_filename);
exit (EXIT_FAILURE);
}
sprintf (type, "t%x", (0xFFF & regs.r[2] >> 8));
#endif
sprintf (header, "Split:%s%s=%d=%s|", out_filename, orig_ext, /* Create the output */
(int) (file_length / (disk_size - 7 - strlen (out_filename) - /* file header. */
strlen (orig_ext)) + 1), type);
file_number = 0; /* Initialise file number counter. */
in_position = 0; /* Initialise source file position pointer. */
while (file_length - in_position > 0) { /* If any data left to transfer */
file_number++; /* increment file number counter. */
numtostr (file_number, fnum); /* Convert to a number. */
while (interactive == 1) { /* If interactive option selected, ask for */
printf ("Enter path for %s%s%s (Return for %s) :\n", /* destination of output file. */
out_filename, fnum, file_ext,
out_path[0] == '\0' ? "current directory" : out_path);
gets (string); /* Get output destination. */
if (strchr (string, ' ') != NULL) {
printf ("Invalid path name.\n");
continue;
}
if (string[0] != '\0') { /* If nothing entered, then use the default. */
strcpy (out_path, string);
i = strlen (out_path);
if (out_path[i - 1] != FILE_SEPARATOR)
if (!COLON || (COLON && out_path[i - 1] != ':')) {
out_path[i] = FILE_SEPARATOR;
out_path[i + 1] = '\0';
}
}
interactive = interactive | 2; /* Set flag to say data has been accepted. */
}
interactive = interactive & 1; /* Mask off unrequired data. */
/* Create the full output filename. */
sprintf (out_name, "%s%s%s%s", out_path, out_filename, fnum, file_ext);
if (file_number > 1) { /* If it's not the first part, */
numtostr (file_number, fnum); /* create a smaller header. */
sprintf (header, "Sp:%s%s=%s|", out_filename, orig_ext, fnum);
}
#ifdef ACORN
regs.r[0] = 7; /* Create the file with SWI */
regs.r[1] = (int) out_name; /* OS_File 7 */
regs.r[2] = 0xdeaddead;
regs.r[3] = 0xdeaddead;
regs.r[4] = 0;
regs.r[5] = (int) MIN (file_length - in_position + strlen (header), disk_size);
if ((err = _kernel_swi (SWI_OS_File, ®s, ®s)) != NULL) {
fprintf (stderr, "Fatal error opening %s for output:\n-- %s\n", out_name, err->errmess);
exit (EXIT_FAILURE);
}
#endif
out_file = fopen (out_name, "wb"); /* Open output file. */
if (out_file == NULL) { /* Report if error, and stop. */
fprintf (stderr, "Fatal error opening %s for output.\n", out_name);
exit (1);
}
out_position = 0; /* Initialise output file position pointer. */
printf ("Writing data to %s\n", out_name);
fprintf (out_file, header); /* Write the header information, */
out_position = (long) strlen (header); /* and update the output file pointer. */
if (disk_size > file_length - in_position + out_position) /* Set the size of the file we */
disk_size = file_length - in_position + out_position; /* want to write. */
while (disk_size - out_position > 0) { /* While there's any data left */
if (disk_size - out_position < read_size) /* to transfer */
data_size = disk_size - out_position;
else
data_size = read_size;
bytes_read = fread (buffer, 1, (size_t) data_size, source_file); /* read */
bytes_written = fwrite (buffer, 1, (size_t) bytes_read, out_file); /* and write. */
/* Check to see that all the data has been transfered ok. */
if (bytes_written < data_size && bytes_written < file_length - out_position) {
fprintf (stderr, "Fatal error while writing %s\n", out_name);
exit (EXIT_FAILURE); /* If unsucessfull, stop. */
}
in_position += bytes_read; /* Update the file position */
out_position += bytes_written; /* pointers. */
}
fclose (out_file); /* Close output file. */
#ifdef ACORN
regs.r[0] = 18; /* Set the filetype with SWI */
regs.r[1] = (int) out_name; /* OS_File 18 */
regs.r[2] = SPLIT_FILETYPE;
err = _kernel_swi (SWI_OS_File, ®s, ®s);
#endif
}
fclose (source_file); /* Close source file */
free (buffer); /* and free buffer. */
fprintf (stderr, "%ld bytes written to %d %s.\n", in_position +
(int) (file_number * (7 + strlen (source_filename))) + 4 + strlen (type),
file_number, (file_number == 1) ? "file" : "files"); /* Report status. */
fprintf (stderr, "Use : joinf %s01%s \nto restore file.\n",
out_filename, (file_ext[0] == '\0') ? "" : ".spt");
exit (EXIT_SUCCESS); /* and finish. */
}